/**************************************************************************************************
*******
**************************************************************************************************/


/* Peripheral group ----------------------------------------------------------- */
/** @defgroup GPDMA	GPDMA (General Purpose Direct Memory Access)
 * @ingroup LPC177x_8xCMSIS_FwLib_Drivers
 * @{
 */

#ifndef __DMA_H_
#define __DMA_H_

/* Includes ------------------------------------------------------------------- */
#include "bus_dev.h"


#ifdef __cplusplus
extern "C"
{
#endif

/* Public Macros -------------------------------------------------------------- */
/** @defgroup GPDMA_Public_Macros GPDMA Public Macros
 * @{
 */

/** DMAC Connection number definitions */
typedef enum{
    DMA_CONN_MEM=0,//               ((0))          	/*memory*/
    DMA_CONN_SPI0_Tx=1,//		    ((0UL))			/** SSP0 Tx */
    DMA_CONN_SPI0_Rx,// 		    ((1UL)) 		/** SSP0 Rx */
    DMA_CONN_SPI1_Tx,// 		    ((2UL)) 		/** SSP1 Tx */
    DMA_CONN_SPI1_Rx,// 		    ((3UL)) 		/** SSP1 Rx */
  
    DMA_CONN_I2C0_Tx=9,// 	    	((8UL)) 		/** IIC0 Tx */
    DMA_CONN_I2C0_Rx,//		    	((9UL))			/** IIC0 Rx */
    DMA_CONN_I2C1_Tx,//		    	((10UL))		/** IIC1 Tx */
    DMA_CONN_I2C1_Rx,// 		    ((11UL)) 		/** IIC1 Rx */
  
    DMA_CONN_UART0_Tx,//		    ((10UL)) 		/** UART0 Tx */
    DMA_CONN_UART0_Rx,//		    ((11UL)) 		/** UART0 Rx */
    DMA_CONN_UART1_Tx,//		    ((12UL)) 		/** UART1 Tx */
    DMA_CONN_UART1_Rx,//		    ((13UL)) 		/** UART1 Rx */
} DMA_CONN_e;


/** Burst size in Source and Destination definitions */
#define DMA_BSIZE_1 	((0UL)) /**< Burst size = 1 */
#define DMA_BSIZE_4 	((1UL)) /**< Burst size = 4 */
#define DMA_BSIZE_8 	((2UL)) /**< Burst size = 8 */
#define DMA_BSIZE_16 	((3UL)) /**< Burst size = 16 */
#define DMA_BSIZE_32 	((4UL)) /**< Burst size = 32 */
#define DMA_BSIZE_64 	((5UL)) /**< Burst size = 64 */
#define DMA_BSIZE_128   ((6UL)) /**< Burst size = 128 */
#define DMA_BSIZE_256   ((7UL)) /**< Burst size = 256 */

/** Width in Source transfer width and Destination transfer width definitions */
#define DMA_WIDTH_BYTE 		((0UL)) /**< Width = 1 byte */
#define DMA_WIDTH_HALFWORD 	((1UL)) /**< Width = 2 bytes */
#define DMA_WIDTH_WORD 		((2UL)) /**< Width = 4 bytes */
#define DMA_WIDTH_2WORD     ((3UL)) /**< Width = 8 bytes */
#define DMA_WIDTH_4WORD     ((4UL)) /**< Width = 16 bytes */
#define DMA_WIDTH_8WORD     ((5UL)) /**< Width = 32 bytes */




/** DMAC Address Increment definitions */
#define DMA_INC_INC 	    ((0UL)) /**< Increment */
#define DMA_INC_DEC 	    ((1UL)) /**< Decrement */
#define DMA_INC_NCHG 	    ((2UL)) /**< No change */


/**
 * @}
 */


/* Private Macros ------------------------------------------------------------- */
/** @defgroup GPDMA_Private_Macros GPDMA Private Macros
 * @{
 */

/* --------------------- BIT DEFINITIONS -------------------------------------- */
/*********************************************************************//**
 * Macro defines for DMA Interrupt Status register
 **********************************************************************/
#define DMA_DMACIntStat_Ch(n)			(((1UL<<n)&0xFF))
#define DMA_DMACIntStat_BITMASK		    ((0xFF))

/*********************************************************************//**
 * Macro defines for DMA Interrupt Terminal Count Request Status register
 **********************************************************************/
#define DMA_DMACIntTCStat_Ch(n)		    (((1UL<<n)&0xFF))
#define DMA_DMACIntTCStat_BITMASK		((0xFF))

/*********************************************************************//**
 * Macro defines for DMA Interrupt Terminal Count Request Clear register
 **********************************************************************/
#define DMA_DMACIntTCClear_Ch(n)		(((1UL<<n)&0xFF))
#define DMA_DMACIntTCClear_BITMASK	((0xFF))

/*********************************************************************//**
 * Macro defines for DMA Interrupt Error Status register
 **********************************************************************/
#define DMA_DMACIntErrStat_Ch(n)		(((1UL<<n)&0xFF))
#define DMA_DMACIntErrStat_BITMASK	((0xFF))

/*********************************************************************//**
 * Macro defines for DMA Interrupt Tfr Clear register
 **********************************************************************/
#define DMA_DMACIntTfrClr_Ch(n)		(((1UL<<n)&0xFF))
#define DMA_DMACIntTfrClr_BITMASK		((0xFF))

/*********************************************************************//**
 * Macro defines for DMA Interrupt Block Clear register
 **********************************************************************/
#define DMA_DMACIntBlockClr_Ch(n)		(((1UL<<n)&0xFF))
#define DMA_DMACIntBlockClr_BITMASK		((0xFF))

/*********************************************************************//**
 * Macro defines for DMA Interrupt SrcTran Clear register
 **********************************************************************/
#define DMA_DMACIntSrcTranClr_Ch(n)		(((1UL<<n)&0xFF))
#define DMA_DMACIntSrcTranClr_BITMASK		((0xFF))

/*********************************************************************//**
 * Macro defines for DMA Interrupt DstTran Clear register
 **********************************************************************/
#define DMA_DMACIntDstTranClr_Ch(n)		(((1UL<<n)&0xFF))
#define DMA_DMACIntDstTranClr_BITMASK		((0xFF))

/*********************************************************************//**
 * Macro defines for DMA Interrupt Error Clear register
 **********************************************************************/
#define DMA_DMACIntErrClr_Ch(n)		(((1UL<<n)&0xFF))
#define DMA_DMACIntErrClr_BITMASK		((0xFF))

/*********************************************************************//**
 * Macro defines for DMA Raw Interrupt Terminal Count Status register
 **********************************************************************/
#define DMA_DMACRawIntTCStat_Ch(n)	(((1UL<<n)&0xFF))
#define DMA_DMACRawIntTCStat_BITMASK	((0xFF))

/*********************************************************************//**
 * Macro defines for DMA Raw Error Interrupt Status register
 **********************************************************************/
#define DMA_DMACRawIntErrStat_Ch(n)	(((1UL<<n)&0xFF))
#define DMA_DMACRawIntErrStat_BITMASK	((0xFF))

/*********************************************************************//**
 * Macro defines for DMA Enabled Channel register
 **********************************************************************/
#define DMA_DMACEnbldChns_Ch(n)		(((1UL<<n)&0xFF))
#define DMA_DMACEnbldChns_BITMASK		((0xFF))

/*********************************************************************//**
 * Macro defines for DMA Software Burst Request register
 **********************************************************************/
#define	DMA_DMACSoftBReq_Src(n)		(((1UL<<n)&0xFFFF))
#define DMA_DMACSoftBReq_BITMASK		((0xFFFF))

/*********************************************************************//**
 * Macro defines for DMA Software Single Request register
 **********************************************************************/
#define DMA_DMACSoftSReq_Src(n) 		(((1UL<<n)&0xFFFF))
#define DMA_DMACSoftSReq_BITMASK		((0xFFFF))

/*********************************************************************//**
 * Macro defines for DMA Software Last Burst Request register
 **********************************************************************/
#define DMA_DMACSoftLBReq_Src(n)		(((1UL<<n)&0xFFFF))
#define DMA_DMACSoftLBReq_BITMASK		((0xFFFF))

/*********************************************************************//**
 * Macro defines for DMA Software Last Single Request register
 **********************************************************************/
#define DMA_DMACSoftLSReq_Src(n) 		(((1UL<<n)&0xFFFF))
#define DMA_DMACSoftLSReq_BITMASK		((0xFFFF))

/*********************************************************************//**
 * Macro defines for DMA Configuration register
 **********************************************************************/
#define DMA_DMAC_E				        ((0x01))	 /**< DMA Controller enable*/
#define DMA_DMAC_D				        ((0x00))	 /**< DMA Controller disable*/
#define DMA_DMAC_INT_E				    ((0x01))	 /**< DMA Controller Interrupt enable*/


/*********************************************************************//**
 * Macro defines for DMA Synchronization register
 **********************************************************************/
#define DMA_DMACSync_Src(n)			(((1UL<<n)&0xFFFF))
#define DMA_DMACSync_BITMASK			((0xFFFF))

/*********************************************************************//**
 * Macro defines for DMA Request Select register
 **********************************************************************/
#define DMA_DMAReqSel_Input(n)		(((1UL<<(n-8))&0xFF))
#define DMA_DMAReqSel_BITMASK			((0xFF))

/*********************************************************************//**
 * Macro defines for DMA Channel Linked List Item registers
 **********************************************************************/
/** DMAC Channel Linked List Item registers bit mask*/
#define DMA_DMACCxLLI_BITMASK 		((0xFFFFFFFC))

/*********************************************************************//**
 * Macro defines for DMA channel control registers
 **********************************************************************/
/** Transfer size*/
#define DMA_DMACCxControl_TransferSize(n) (n&0x7FF)
/** Source burst size*/
#define DMA_DMACCxControl_SMSize(n)		(((n&0x07)<<14))
/** Destination burst size*/
#define DMA_DMACCxControl_DMSize(n)		(((n&0x07)<<11))
/** Source transfer width*/
#define DMA_DMACCxControl_SWidth(n)		(((n&0x07)<<4))
/** Destination transfer width*/
#define DMA_DMACCxControl_DWidth(n)		(((n&0x07)<<1))
/** Source increment*/
#define DMA_DMACCxControl_SInc(n)		(((n&0x03)<<9))
/** Destination increment*/
#define DMA_DMACCxControl_DInc(n)		(((n&0x03)<<7))

/*********************************************************************//**
 * Macro defines for DMA Channel Configuration registers
 **********************************************************************/
/** DMAC channel write bit enable*/
#define DMA_DMACCxConfig_E(n) 					    ((0x100UL<<n))
/** DMAC channel int mask bit enable*/
#define DMA_DMACCxIntMask_E(n) 					    ((0x100UL<<n))

/** Source peripheral*/
#define DMA_DMACCxConfig_SrcPeripheral(n) 	    (((n&0x1F)))
/** Destination peripheral*/
#define DMA_DMACCxConfig_DestPeripheral(n) 	    (((n&0x1F)<<4))
/** This value indicates the type of transfer*/
#define DMA_DMACCxConfig_TransferType(n) 		(((n&0x7)<<20))
/** Interrupt error mask*/
#define DMA_DMACCxConfig_IE 					((1UL<<14))
/** Terminal count interrupt mask*/
#define DMA_DMACCxConfig_ITC 					((1UL<<15))
/** Lock*/
#define DMA_DMACCxConfig_L 					    ((1UL<<16))
/** Active*/
#define DMA_DMACCxConfig_A 					    ((1UL<<17))
/** Halt*/
#define DMA_DMACCxConfig_H 					    ((1UL<<18))
/** DMAC Channel Configuration registers bit mask */
#define DMA_DMACCxConfig_BITMASK				((0x7FFFF))

/**
 * @}
 */
#define DMA_TRANSFERTYPE_M2M 		    ((0UL))
/** DMAC Transfer type definitions: Memory to peripheral - DMA control */
#define DMA_TRANSFERTYPE_M2P 		    ((1UL))
/** DMAC Transfer type definitions: Peripheral to memory - DMA control */
#define DMA_TRANSFERTYPE_P2M 		    ((2UL))
/** DMAC Source peripheral to destination peripheral - DMA control */
#define DMA_TRANSFERTYPE_P2P 		    ((3UL))

/** If dstnation address is flash, should set this bit- DMA control */
#define DMA_DST_XIMT_IS_FLASH 		    ((0UL))
/** DMAC Source peripheral to destination peripheral - DMA control */
#define DMA_DST_XIMT_NOT_FLASH 		    ((1UL))

#define DMA_GET_MAX_TRANSPORT_SIZE(ch)      ((ch == DMA_CH_0) ? 0x7ff : 0x1f)



/**
 * @brief DMAC Interrupt clear status enumeration
 */
typedef enum{
	DMA_STATCLR_INTTC,	/**< GPDMA Interrupt Terminal Count Request Clear */
	DMA_STATCLR_INTERR	/**< GPDMA Interrupt Error Clear */
}DMA_StateClear_Type;
    
/**
 * @brief DMAC Channel configuration structure type definition
 */
typedef struct {
	uint32_t    transf_size;	/**< Length/Size of transfer */
	
	uint8_t     sinc;
    uint8_t     src_tr_width;
    uint8_t     src_msize;
	uint32_t    src_addr;
	
	uint8_t     dinc;
    uint8_t     dst_tr_width;
    uint8_t     dst_msize;
	uint32_t    dst_addr;

    bool        enable_int;
} DMA_CH_CFG_t;

typedef enum{
	DMA_CH_0 = 0,		
	DMA_CH_1,
	DMA_CH_2,
	DMA_CH_3,
	DMA_CH_NUM,
} DMA_CH_t;

/**
 * @brief DMAC Linker List Item structure type definition
 */
typedef struct {
	uint32_t  src_addr;	/**< Source Address */
	uint32_t  dst_addr;	/**< Destination address */
	uint32_t  lli;	    /**< Next LLI address, otherwise set to '0' */
	uint32_t  ctrl;	    /**< GPDMA Control of this LLI */
} DMA_LLI_t;

/**
 * @brief DMAC callback definition
 */
typedef void (*DMA_Hdl_t)(DMA_CH_t);

typedef struct {
    DMA_CH_t    dma_channel;
	DMA_Hdl_t   evt_handler;
}HAL_DMA_t;

typedef struct {
	uint8_t     init_ch;
    uint8_t     interrupt;
    uint8_t     xmit_busy;
    uint8_t     xmit_flash;
    DMA_Hdl_t   evt_handler;	
} DMA_CH_Ctx_t;

int hal_dma_init_channel(HAL_DMA_t cfg);
int hal_dma_config_channel(DMA_CH_t ch, DMA_CH_CFG_t* cfg);
int hal_dma_start_channel(DMA_CH_t ch);
int hal_dma_stop_channel(DMA_CH_t ch);
int hal_dma_wait_channel_complete(DMA_CH_t ch);
int hal_dma_status_control(DMA_CH_t ch);
int hal_dma_init(void);
int hal_dma_deinit(void);
void __attribute__((used)) hal_DMA_IRQHandler(void);




#ifdef __cplusplus
}
#endif

#endif /* __LPC177X_8X_GPDMA_H_ */

/**
 * @}
 */

/* --------------------------------- End Of File ------------------------------ */
